﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
using Painter3D.RenderSys;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;

namespace Painter3D.UI
{
    /// <summary>
    /// 用于小纹理的拼凑，以方便使用
    /// </summary>
    class TextureGrid
    {
        private readonly Texture2D texture;
        private Dictionary<string, UVStruct> tilesInfo;
        public enum ModeEnum
        {
            /// <summary>
            /// 同大小排列
            /// </summary>
            Fixed,
            /// <summary>
            /// 紧密排列
            /// </summary>
            Tight,
            /// <summary>
            /// 网格排列
            /// </summary>
            Grid,
        }
        public struct UVStruct
        {
            public Vector2 uv1;
            public Vector2 uv2;

            public UVStruct(Vector2 uv1, Vector2 uv2)
            {
                this.uv1 = uv1;
                this.uv2 = uv2;
            }

            public UVStruct(float x1, float y1, float x2, float y2)
            {
                this.uv1.X = x1;
                this.uv1.Y = y1;
                this.uv2.X = x2;
                this.uv2.Y = y2;
            }
        }

        /// <summary>
        /// 生成一个图片堆砌
        /// </summary>
        /// <param name="infos">图片信息 <name·路径></param>
        /// <param name="mode">堆砌模式</param>
        public TextureGrid(Dictionary<string, string> infos, ModeEnum mode, int size)
        {
            tilesInfo = new Dictionary<string, UVStruct>(infos.Count);
            GetGridCount(infos.Count, out int widthCount, out int heightCount);
            using (Image<Rgba32> texture = new Image<Rgba32>(widthCount * size, heightCount * size))
            {
                int index = 0;
                foreach (var info in infos)
                {
                    using (Image<Rgba32> image = Image.Load<Rgba32>(info.Value))
                    {
                        int x = index % widthCount * size;
                        int y = index / heightCount * size;
                        tilesInfo.Add(info.Key, new UVStruct((float)(x) / texture.Width, (float)(y) / texture.Height, (float)(x+ size) / texture.Width, (float)(y + size) / texture.Height));
                        texture.Mutate(pixel => pixel.DrawImage(image, new Point(x, y), 1));
                    }
                    index++;
                }

                var pixels = new List<byte>(4 * texture.Width * texture.Height);
                for (int y = 0; y < texture.Height; y++)
                {
                    var row = texture.GetPixelRowSpan(y);
                    for (int x = 0; x < texture.Width; x++)
                    {
                        pixels.Add(row[x].R);
                        pixels.Add(row[x].G);
                        pixels.Add(row[x].B);
                        pixels.Add(row[x].A);
                    }
                }
                this.texture = new Texture2D(texture.Width, texture.Height, pixels.ToArray());
            }
        }
        /// <summary>
        /// 获取图片瓦片
        /// </summary>
        /// <param name="name">图片名称</param>
        /// <param name="uv">UV位置</param>
        public void GetTile(string name, out UVStruct uv)
        {
            uv = tilesInfo[name];
        }

        public Vector2 GetTileP1(string name)
        {
            return tilesInfo[name].uv1;
        }
        public Vector2 GetTileP2(string name)
        {
            return tilesInfo[name].uv2;
        }

        public IntPtr Id()
        {
            return texture.Id();
        }
        private void GetGridCount(int count, out int width, out int height)
        {
            width = 0;
            height = 0;
            while (width * height < count)
            {
                if (width < height)
                {
                    width++;
                }
                else
                {
                    height++;
                }
            }
        }
    }
}
